package com.example.examsystem.service;

import com.example.examsystem.dto.ExamResultDto;
import com.example.examsystem.dto.PageResponse;
import com.example.examsystem.exception.BusinessException;
import com.example.examsystem.model.ExamResult;
import com.example.examsystem.repository.ExamResultRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.stream.Collectors;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

/**
 * 考试结果服务
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class ExamResultService {
    
    private final ExamResultRepository examResultRepository;
    
    /**
     * 获取考试结果
     */
    public ExamResultDto getExamResult(Long examId, Long userId) {
        log.debug("获取考试结果 - 考试ID: {}, 用户ID: {}", examId, userId);
        
        ExamResult examResult = examResultRepository.findByExamIdAndUserId(examId, userId)
            .orElseThrow(() -> new BusinessException("考试结果不存在"));
        
        return convertToDto(examResult);
    }
    
    /**
     * 保存考试结果
     */
    @Transactional
    public ExamResultDto saveExamResult(ExamResultDto examResultDto) {
        log.debug("保存考试结果 - 考试ID: {}, 用户ID: {}", 
                examResultDto.getExamId(), examResultDto.getUserId());
        
        ExamResult examResult = new ExamResult();
        examResult.setExamId(examResultDto.getExamId());
        examResult.setUserId(examResultDto.getUserId());
        examResult.setScore(examResultDto.getScore());
        examResult.setTotalScore(examResultDto.getTotalScore());
        examResult.setCorrectCount(examResultDto.getCorrectCount());
        examResult.setTotalCount(examResultDto.getTotalCount());
        examResult.setStartTime(examResultDto.getStartTime());
        examResult.setEndTime(examResultDto.getEndTime());
        examResult.setDuration(examResultDto.getDuration());
        examResult.setStatus(examResultDto.getStatus());
        examResult.setCreatedAt(LocalDateTime.now());
        examResult.setUpdatedAt(LocalDateTime.now());
        
        ExamResult saved = examResultRepository.save(examResult);
        log.info("考试结果保存成功 - ID: {}", saved.getId());
        
        return convertToDto(saved);
    }
    
    /**
     * 获取用户的考试结果列表
     */
    public List<ExamResultDto> getUserExamResults(Long userId) {
        log.debug("获取用户考试结果列表 - 用户ID: {}", userId);
        
        List<ExamResult> results = examResultRepository.findByUserIdOrderByCreatedAtDesc(userId);
        return results.stream()
                .map(this::convertToDto)
                .collect(Collectors.toList());
    }
    
    /**
     * 转换为DTO
     */
    private ExamResultDto convertToDto(ExamResult examResult) {
        ExamResultDto dto = new ExamResultDto();
        dto.setId(examResult.getId());
        dto.setExamId(examResult.getExamId());
        dto.setUserId(examResult.getUserId());
        dto.setScore(examResult.getScore());
        dto.setTotalScore(examResult.getTotalScore());
        dto.setCorrectCount(examResult.getCorrectCount());
        dto.setTotalCount(examResult.getTotalCount());
        dto.setStartTime(examResult.getStartTime());
        dto.setEndTime(examResult.getEndTime());
        dto.setDuration(examResult.getDuration());
        dto.setStatus(examResult.getStatus());
        dto.setCreatedAt(examResult.getCreatedAt());
        dto.setUpdatedAt(examResult.getUpdatedAt());
        
        return dto;
    }

    /**
     * 分页查询考试成绩列表
     */
    public PageResponse<ExamResultDto> getExamResults(int page, int size, Long examId, Long userId,
                                                     String username, String grade, Boolean passStatus, Boolean published) {
        log.debug("查询考试成绩列表 - 页码: {}, 大小: {}", page, size);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
        // TODO: Implement query with filters
        Page<ExamResult> resultPage = examResultRepository.findAll(pageable);
        
        List<ExamResultDto> content = resultPage.getContent().stream()
            .map(this::convertToDto)
            .collect(Collectors.toList());
        
        return new PageResponse<>(
            content,
            resultPage.getNumber(),
            resultPage.getSize(),
            resultPage.getTotalElements(),
            resultPage.getTotalPages()
        );
    }

    /**
     * 获取考试成绩详情（重载方法）
     */
    public ExamResultDto getExamResult(Long id) {
        log.debug("获取考试成绩详情 - ID: {}", id);
        
        ExamResult examResult = examResultRepository.findById(id)
            .orElseThrow(() -> new BusinessException("考试成绩不存在"));
        
        return convertToDto(examResult);
    }

    /**
     * 根据考试记录ID获取成绩
     */
    public ExamResultDto getResultByRecordId(Long examRecordId) {
        log.debug("根据考试记录ID获取成绩 - 记录ID: {}", examRecordId);
        // TODO: Add repository method or implement logic
        throw new BusinessException("方法待实现");
    }

    /**
     * 生成考试成绩
     */
    @Transactional
    public ExamResultDto generateResult(Long examRecordId) {
        log.debug("生成考试成绩 - 记录ID: {}", examRecordId);
        // TODO: Implement result generation logic
        throw new BusinessException("方法待实现");
    }

    /**
     * 更新成绩反馈
     */
    @Transactional
    public ExamResultDto updateFeedback(Long id, String feedback) {
        log.debug("更新成绩反馈 - ID: {}", id);
        // TODO: Implement feedback update logic
        throw new BusinessException("方法待实现");
    }

    /**
     * 发布成绩
     */
    @Transactional
    public ExamResultDto publishResult(Long id, Long publisherId) {
        log.debug("发布成绩 - ID: {}, 发布者ID: {}", id, publisherId);
        // TODO: Implement result publishing logic
        throw new BusinessException("方法待实现");
    }

    /**
     * 批量发布成绩
     */
    @Transactional
    public int batchPublishResults(Long examId, Long publisherId) {
        log.debug("批量发布成绩 - 考试ID: {}, 发布者ID: {}", examId, publisherId);
        // TODO: Implement batch publishing logic
        return 0;
    }

    /**
     * 获取用户的考试成绩
     */
    public PageResponse<ExamResultDto> getMyResults(Long userId, int page, int size, Long examId, Boolean published) {
        log.debug("获取用户考试成绩 - 用户ID: {}", userId);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
        List<ExamResult> results = examResultRepository.findByUserIdOrderByCreatedAtDesc(userId);
        
        // TODO: Apply filters and pagination properly
        List<ExamResultDto> content = results.stream()
            .map(this::convertToDto)
            .collect(Collectors.toList());
        
        return new PageResponse<>(content, page, size, content.size(), 1);
    }

    /**
     * 获取考试成绩统计信息
     */
    public Map<String, Object> getResultStatistics(Long examId) {
        log.debug("获取考试成绩统计信息 - 考试ID: {}", examId);
        
        List<ExamResult> results = examResultRepository.findByExamIdOrderByScoreDesc(examId);
        Map<String, Object> statistics = new HashMap<>();
        statistics.put("totalCount", results.size());
        // TODO: Add more statistics
        
        return statistics;
    }

    /**
     * 获取考试排名
     */
    public List<ExamResultDto> getExamRanking(Long examId) {
        log.debug("获取考试排名 - 考试ID: {}", examId);
        
        List<ExamResult> results = examResultRepository.findByExamIdOrderByScoreDesc(examId);
        return results.stream()
            .map(this::convertToDto)
            .collect(Collectors.toList());
    }
}



